"""
性能监控中间件

记录 API 响应时间、数据库查询时间等性能指标。
"""
import time
import logging
from typing import Callable
from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.types import ASGIApp

logger = logging.getLogger(__name__)


class PerformanceMonitorMiddleware(BaseHTTPMiddleware):
    """
    性能监控中间件
    
    自动记录每个 API 请求的：
    - 响应时间
    - 请求方法和路径
    - 响应状态码
    
    Examples:
        >>> from fastapi import FastAPI
        >>> from app.middleware.performance_monitor import PerformanceMonitorMiddleware
        >>> 
        >>> app = FastAPI()
        >>> app.add_middleware(PerformanceMonitorMiddleware)
    
    Note:
        - 响应时间超过 1 秒会记录为 WARNING
        - 响应时间超过 5 秒会记录为 ERROR
        - 所有请求都会记录基本信息（DEBUG 级别）
    """
    
    def __init__(self, app: ASGIApp, slow_threshold: float = 1.0, very_slow_threshold: float = 5.0):
        """
        初始化性能监控中间件
        
        Args:
            app: ASGI 应用
            slow_threshold: 慢请求阈值（秒），默认 1.0
            very_slow_threshold: 非常慢请求阈值（秒），默认 5.0
        """
        super().__init__(app)
        self.slow_threshold = slow_threshold
        self.very_slow_threshold = very_slow_threshold
    
    async def dispatch(self, request: Request, call_next: Callable) -> Response:
        """
        处理请求并记录性能指标
        
        Args:
            request: HTTP 请求对象
            call_next: 下一个中间件或路由处理器
        
        Returns:
            Response: HTTP 响应对象
        """
        # 记录开始时间
        start_time = time.time()
        
        # 处理请求
        response = await call_next(request)
        
        # 计算响应时间
        process_time = time.time() - start_time
        
        # 构建日志消息
        method = request.method
        path = request.url.path
        status_code = response.status_code
        
        log_message = (
            f"{method} {path} - "
            f"Status: {status_code} - "
            f"Time: {process_time:.3f}s"
        )
        
        # 根据响应时间选择日志级别
        if process_time >= self.very_slow_threshold:
            logger.error(f"⚠️  VERY SLOW REQUEST: {log_message}")
        elif process_time >= self.slow_threshold:
            logger.warning(f"⏱️  SLOW REQUEST: {log_message}")
        else:
            logger.debug(log_message)
        
        # 在响应头中添加处理时间
        response.headers["X-Process-Time"] = f"{process_time:.3f}"
        
        return response


def log_db_query_time(query_name: str, start_time: float) -> None:
    """
    记录数据库查询时间
    
    用于手动记录特定数据库查询的执行时间。
    
    Args:
        query_name: 查询名称或描述
        start_time: 查询开始时间（time.time()）
    
    Examples:
        >>> start = time.time()
        >>> users = db.query(User).all()
        >>> log_db_query_time("get_all_users", start)
    
    Note:
        - 查询时间超过 0.5 秒会记录为 WARNING
        - 查询时间超过 2 秒会记录为 ERROR
    """
    query_time = time.time() - start_time
    
    if query_time >= 2.0:
        logger.error(f"⚠️  VERY SLOW QUERY: {query_name} - {query_time:.3f}s")
    elif query_time >= 0.5:
        logger.warning(f"⏱️  SLOW QUERY: {query_name} - {query_time:.3f}s")
    else:
        logger.debug(f"DB QUERY: {query_name} - {query_time:.3f}s")


class QueryTimer:
    """
    数据库查询计时器（上下文管理器）
    
    使用 with 语句自动记录查询时间。
    
    Examples:
        >>> with QueryTimer("get_user_documents"):
        ...     documents = db.query(Document).filter(
        ...         Document.upload_user_id == user_id
        ...     ).all()
    """
    
    def __init__(self, query_name: str):
        """
        初始化查询计时器
        
        Args:
            query_name: 查询名称或描述
        """
        self.query_name = query_name
        self.start_time = None
    
    def __enter__(self):
        """开始计时"""
        self.start_time = time.time()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """结束计时并记录"""
        if self.start_time is not None:
            log_db_query_time(self.query_name, self.start_time)


# 性能统计（可选，用于更高级的监控）
class PerformanceStats:
    """
    性能统计工具
    
    收集和汇总性能指标，可用于生成报告或发送到监控系统。
    
    Examples:
        >>> stats = PerformanceStats()
        >>> stats.record_request("/api/documents/list", 0.123, 200)
        >>> stats.get_summary()
    """
    
    def __init__(self):
        """初始化性能统计"""
        self.requests = []
        self.start_time = time.time()
    
    def record_request(self, path: str, duration: float, status_code: int) -> None:
        """
        记录一个请求
        
        Args:
            path: 请求路径
            duration: 响应时间（秒）
            status_code: HTTP 状态码
        """
        self.requests.append({
            "path": path,
            "duration": duration,
            "status_code": status_code,
            "timestamp": time.time()
        })
    
    def get_summary(self) -> dict:
        """
        获取统计摘要
        
        Returns:
            dict: 包含以下统计信息：
                - total_requests: 总请求数
                - avg_response_time: 平均响应时间
                - max_response_time: 最大响应时间
                - min_response_time: 最小响应时间
                - slow_requests: 慢请求数（>1秒）
                - error_requests: 错误请求数（状态码 >= 400）
                - uptime: 运行时间（秒）
        """
        if not self.requests:
            return {
                "total_requests": 0,
                "avg_response_time": 0,
                "max_response_time": 0,
                "min_response_time": 0,
                "slow_requests": 0,
                "error_requests": 0,
                "uptime": time.time() - self.start_time
            }
        
        durations = [r["duration"] for r in self.requests]
        
        return {
            "total_requests": len(self.requests),
            "avg_response_time": sum(durations) / len(durations),
            "max_response_time": max(durations),
            "min_response_time": min(durations),
            "slow_requests": sum(1 for d in durations if d > 1.0),
            "error_requests": sum(1 for r in self.requests if r["status_code"] >= 400),
            "uptime": time.time() - self.start_time
        }
    
    def reset(self) -> None:
        """重置统计数据"""
        self.requests = []
        self.start_time = time.time()


# 全局性能统计实例
performance_stats = PerformanceStats()

